<template>
  <div class="containers">
    <div class="tools_" >
      <a-icon type="arrow-left" @click="handleUndo" />
      <a-icon type="arrow-right" @click="handleRedo" />
      <a-divider type="vertical" />
      <a-icon type="zoom-in" @click="handleZoomIn" />
      <a-icon type="zoom-out" @click="handleZoomOut" />
      <a-divider type="vertical" />
      <a-icon type="download" />
    </div>
    <!-- <div style="margin-left:50px;padding-top:10px;">
        <a-button icon="icon-left-arrow" @click="handleUndo" type="primary" size="small">后退</a-button>
        <a-button @click="handleRedo" style="margin-left:20px"  size="small">前进</a-button>
        <a-button @click="handleDownload" style="margin-left:20px" type="primary" size="small">下载</a-button>
        <a-upload
            name="file"
            :multiple="true"
            @change="handleOnchangeFile"
        >
          <a-button style="margin-left:20px" size="small">导入</a-button>
        </a-upload>
    </div> -->
    <template>
        <div class="canvas" ref="canvas"></div>
        <div id="js-properties-panel" class="panel"></div>
        <ul class="buttons">
          <li>
            <a ref="saveDiagram" href="javascript:" title="保存为bpmn">保存为bpmn</a>
          </li>
          <li>
            <a ref="saveSvg" href="javascript:" title="保存为svg">保存为svg</a>
          </li>
        </ul>
    </template>
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnModeler from 'bpmn-js/lib/Modeler'
import axios from 'axios'
import { xmlStr } from './xmlStr'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import propertiesPanelModule from 'bpmn-js-properties-panel'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
// 以下为bpmn工作流绘图工具的样式
import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'
import customTranslate from './customTranslate/customTranslate'
var customTranslateModule = {
  translate: ['value', customTranslate]
}
import { Icon } from 'ant-design-vue'

const IconFont = Icon.createFromIconfontCN({
  scriptUrl: '//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js'
})
export default {
  name: '',
  components: {
    IconFont
  },
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {},
  // 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成，一般在该过程进行 Ajax 交互
  mounted() {
    this.init()
  },
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null,
      // loading: true,
      xmlUrl: '',
      // defaultXmlStr: ''
      defaultXmlStr: xmlStr,
      zoom: 1
    }
  },
  // 方法集合
  methods: {
    async init() {
      // this.loading = true
      this.xmlUrl = await this.getXmlUrl()
      // this.loading = false
      this.$nextTick(() => {
        this.initBpmn()
      })
    },
    getXmlUrl() {
      return new Promise(resolve => {
        setTimeout(() => {
          // const url = 'https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/mock1.bpmn'
          const url = ''
          resolve(url)
        }, 1000)
      })
    },
    initBpmn() {
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        // 添加控制板
        propertiesPanel: {
          parent: '#js-properties-panel'
        },
        additionalModules: [
          // 左边工具栏以及节点
          propertiesProviderModule,
          // 右边的工具栏
          propertiesPanelModule,
          customTranslateModule// 汉化
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })
      this.createNewDiagram()
    },
    async createNewDiagram() {
      const that = this
      let bpmnXmlStr = ''
      if (this.xmlUrl === '') {
        bpmnXmlStr = this.defaultXmlStr
        this.transformCanvas(bpmnXmlStr)
      } else {
        const res = await axios({
          method: 'get',
          timeout: 120000,
          url: that.xmlUrl,
          headers: { 'Content-Type': 'multipart/form-data' }
        })
        bpmnXmlStr = res['data']
        this.transformCanvas(bpmnXmlStr)
      }
    },
    // 将字符串转换成图并渲染
    async transformCanvas(bpmnXmlStr) {
      // this.bpmnModeler.importXML(bpmnXmlStr, (err) => {
      //   console.log(err)
      //   if (err) {
      //     console.error(err)
      //   } else {
      //     this.success()
      //   }
      //   // 让图能自适应屏幕
      //   var canvas = this.bpmnModeler.get('canvas')
      //   canvas.zoom('fit-viewport')
      // })
      try {
        const result = await this.bpmnModeler.importXML(bpmnXmlStr)
        const elementRegistry = this.bpmnModeler.get('elementRegistry')
        const modeling = this.bpmnModeler.get('modeling')
        const { warnings } = result
        if (warnings.length > 0) {
          console.error(warnings)
        } else {
          this.success()
        }
        // 让图能自适应屏幕
        var canvas = this.bpmnModeler.get('canvas')
        canvas.zoom('fit-viewport')
        var elementToColor = elementRegistry.get('Task_1hcentk')
        modeling.setColor([elementToColor], {
          stroke: 'green',
          fill: 'rgba(0, 80, 0, 0.4)'
        })
      } catch (err) {
        console.log(err.message, err.warnings)
      }
    },
    success() {
      this.addBpmnListener()
      this.addModelerListener()
      this.shape = this.bpmnModeler.get('canvas')._rootElement
    },
    // 添加绑定事件
    addBpmnListener() {
      const that = this
      // 获取a标签dom节点
      const downloadLink = this.$refs.saveDiagram
      const downloadSvgLink = this.$refs.saveSvg
      // 给图绑定事件，当图有发生改变就会触发这个事件
      this.bpmnModeler.on('commandStack.changed', function() {
        that.saveSVG(function(err, svg) {
          console.log(svg)
          that.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)
        })
        that.saveDiagram(function(err, xml) {
          that.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml)
        })
      })
    },
    addModelerListener() {
      // 监听 modeler
      // const bpmnjs = this.bpmnModeler
      const that = this
      // 'shape.removed'
      const events = ['shape.added', 'shape.move.end', 'connect.end', 'connection.create', 'connection.move']
      events.forEach(function(event) {
        that.bpmnModeler.on(event, e => {
          // var elementRegistry = bpmnjs.get('elementRegistry')
          // var shape = e.element ? elementRegistry.get(e.element.id) : e.shape
        })
      })
    },
    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveSVG(done) {
      // 把传入的done再传给bpmn原型的saveSVG函数调用
      this.bpmnModeler.saveSVG(done)
    },
    // 下载为bpmn格式,done是个函数，调用的时候传入的
    saveDiagram(done) {
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml)
      })
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data)
      // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
      // console.log(link, name, data)
      // const xmlFile = new File([data], 'test.bpmn')
      // console.log(xmlFile)
      if (data) {
        link.className = 'active'
        link.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
        link.download = name
      }
    },
    handleUndo() { // 后退
      this.bpmnModeler.get('commandStack').undo()
    },
    handleRedo() { // 前进
      this.bpmnModeler.get('commandStack').redo()
    },
    handleZoomIn() {
      this.zoom += 0.1
      var canvas = this.bpmnModeler.get('canvas')
      canvas.zoom(this.zoom)
    },
    handleZoomOut() {
      this.zoom -= 0.1
      var canvas = this.bpmnModeler.get('canvas')
      canvas.zoom(this.zoom)
    },
    handleDownload() {
      // this.bpmnModeler.saveXML({ format: true }, (err, data) => {
      //   const dataTrack = 'bpmn'
      //   const a = document.createElement('a')
      //   const name = `diagram.${dataTrack}`
      //   a.setAttribute(
      //     'href',
      //     `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}`
      //   )
      //   a.setAttribute('target', '_blank')
      //   a.setAttribute('dataTrack', `diagram:download-${dataTrack}`)
      //   a.setAttribute('download', name)
      //   document.body.appendChild(a)
      //   a.click()
      //   document.body.removeChild(a)
      // })
    },
    handleOnchangeFile(file) {
      const reader = new FileReader()
      let data = ''
      reader.readAsText(file.raw)
      reader.onload = (event) => {
        data = event.target.result
        this.bpmnModeler.importXML(data, (err) => {
          if (err) {
            this.$message.info('导入失败')
          } else {
            this.$message.success('导入成功')
          }
        })
      }
    }
  },
  // 计算属性
  computed: {}
}
</script>
<style>
.ant-upload-list-item {
  width: 300px !important;
}
</style>
<style scoped>

.loading {
    font-size: 26px;
}
.containers{
	background-color: #ffffff;
	width: 100%;
  height: calc(100vh - 52px);
  padding-top: 10px;
}
.canvas{
	width: 100%;
	height: 100%;
}
.panel{
	position: absolute;
	right: 0;
	top: 120px;
	width: 300px;
}
.buttons {
    position: absolute;
    left: 200px;
    bottom: 20px;
}
.buttons li {
    display: inline-block;
    margin: 5px;
}
.buttons li a {
    color: #999;
    background: #eee;
    cursor: not-allowed;
    padding: 8px;
    border: 1px solid #ccc;
    text-decoration: none;
}
.buttons li a.active {
    color: #333;
    background: #fff;
    cursor: pointer;
}
.tools_{
  display: inline-block;
  margin-left: 150px;
  margin-top:10px ;
  width: 200px;
  background: #FAFAFA;
  border: solid 1px #CCC;
  border-radius: 2px;
  height: 40px;
  line-height: 40px;
}
.tools_ i{
  font-size: 18px;
  margin-left: 10px;
  cursor: pointer;
}
.tools_ i:hover{
  color: rgb(255, 116, 0);
}
</style>
